# Integración del método de autenticación al protocolo babel #

Estado: *Experimental*

Se sigue el Mecanismo de extensión del protocolo babel (RFC 7557),
se define un nuevo TLV denominado **lorauth**.

## Estructura del TLV ##

     0                   1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     |     Type=29   |   Length      |
     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 |        Np     |  Clen         |
	 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	 |            Cipher...
	 +-+-+-+-+-+-+-+-+-+-+-+-+-

Donde:

* **Type**: Es siempre 29.
* **Length**: Es el número de bytes del TLV.
* **Np**: Es el número de paquete del mensaje cifrado siendo enviado.
* **Clen**: El número de bytes de la parte del mensaje cifrado `Cipher`.
* **Cipher**: La parte del mensaje cifrada con la llave RSA privada `PK` de
  la entidad `C`. Esta cadena esta en función del `router-id` y `seqno`
  extraídos del `TLV Router-id` y el `TLV Update`.

Como el mensaje cifrado completo puede tener un tamaño mayor 255 bytes, se
envía en mensaje cifrado en paquetes de tamaño máximo de hasta 254 bytes, y
Np especifica el número de paquete o número de parte del mensaje cifrado
siendo enviado.

Por ejemplo si el mensaje cifrado tiene un total de 512 bytes, se enviará un
total de 3 paquetes:

* 1er paquete: `(Type=29, Length=255, Np=1, Clen=253, Cipher-parte1)`
* 2do paquete: `(Type=29, Length=255, Np=2, Clen=253, Cipher-parte2)`
* 3er paquete: `(Type=29, Length=8, Np=3, Clen=6, Cipher-parte3)`

Se divide en paquetes para matener el campo `Length` a 1 octeto, y seguir
el estandar del [RFC - 6126, sección 4.3](https://tools.ietf.org/html/rfc6126#section-4.3)

## ¿Cuando se utiliza el TLV lorauth? ##

Se utiliza antes de cada `TLV Update` necesariamente (el TLV Update esta
descrito en la
[sección 4.4.9, RFC 6126](https://tools.ietf.org/html/rfc6126#section-4.4.9)
, la especificación del protocolo original), si se recibe
un `TLV Update` al cual no le precede inmediatamente antes el
`TLV lorauth` se ignora el Update.

Todos los `TLV Update` requieren que se incluya el `TLV lorauth`.

Se requieren verificar el `router-id`, `seqno` y prefijo que el nodo anuncia.

* El `router-id` se obtiene del `TLV Router-id` que precede al Update.
* El `seqno` y prefijo (`prefix`) se obtienen del `TLV Update`.

En cada `TLV Update` se seguirá el
[procedimiento de autenticación](README.es.md#Procedimiento_de_autenticación_entre_nodos)

## Modificaciones al protocolo babel original ##

Cuando se está usando la autenticación, se requieren hacer ciertas
modificaciones al protocolo original.

### La Tabla de fuentes (The Source Table) ###

Se modifica la tabla de fuentes (*source table* originalmente
descrita en la sección 3.2.4 del RFC 6126) para almacenar datos
relacionados a la autenticación.

Se agregan dos elementos a cada registro en la tabla de fuentes de
babel, estos dos elementos son `clen` y `cipher`, quedando cada
registro de la siguiente forma:

    (prefix, plen, router-id, seqno, metric, clen, cipher)

* `clen`: Es el número de bytes que ocupa `cipher`.
* `cipher`: Es la última cadena de cifrado que se ha autenticado y que
  satisface `prefix` y el `seqno` del registro correspondiente.

Así cuando se hace un Update se agrega el `TLV lorauth` usando los
elementos `clen` y `cipher` guardados en esta tabla.

Los demás elementos del registro se manejan como en el protocolo
original.

### Selección cadena de cifrado ###

Cada nodo ha recibido de la entidad `C` un conjunto de cadenas cifradas
con `k` elementos.

El problema es que si un nodo captura todos los `TLV lorauth` de un
nodo específico, estará en condiciones de suplantar su identidad. Esto
por que si posee las cadenas de autenticación de un nodo `A`, podrá
anunciar el prefijo del nodo `A` y usar las cadenas de autenticación de
`A` en los `TLV lorauth`. En este caso los nodos que reciban los
*Update* del suplantador comprobarán que `Cipher` en los `TLV lorauth`
son válidos y los aceptarán.

Dado que capturar paquetes en redes inalámbricas es sencillo, para
dificultar el trabajo de obtener todas las cadenas de cifrado de un
nodo A, se puede hacer que el conjunto de cadenas cifradas `c_A` para un
nodo A tenga un orden específico y se envíe de acuerdo al `seqno` y
`router-id` en el *Update* correspondiente.

#### Contenido de cada cadena cifrada ####

Cada cadena cifrada usada por un nodo tiene la forma:

    prefix + "_" + rand6d() + fd(fs(router_id, seqno), nd)

* **prefix**: Es el prefijo o `prefix` asignado al nodo.
* **rand6d()**: Una función que retorna 6 dígitos al azar completando
  ceros, por ejemplo; 041882, 118525, 000095
* **fd(n, nd)**: Una función que aplica: `n % (10^nd)` y lo expresa en
  un número de dígitos igual a `nd`, por ejemplo:
  fd(2012, 2) = 12 , fd(995142, 3) = 142, fd(9101, 2) = 01
* **fs(router_id, seqno)**: Una función que se define como:

  `((seqno*7)+1) xor (((router_id>>32)>>3) & (router_id&0xFFFFFFFF))`
  
  `xor` es la operacion lógica or exclusivo, `>>` es el desplazamiento hacia
  la derecha

La entidad `C` crea un conjunto de cadenas cifradas para un nodo A
de tal forma que se tengan:

    c_A = { prefix_A + "_" + rand6d() + "00",
	        prefix_A + "_" + rand6d() + "01",
			.
			.
			.
			prefix_A + "_" + rand6d() + "99" }

Este caso es cuando el número de elementos `c_A` es `100`.

#### Cadena de cifrado enviada en cada TLV lorauth ####

Del resultado de `fd(fs(router_id, seqno), nd)` se selecciona el
número de elemento a enviar del conjunto de cadenas cifradas.

Por ejemplo si: router_id=0x1122334455667788, seqno=0x1955
resulta en el numero de elemento o indice 20. Entonces se usará la
cadena `c_A[20]` para el `TLV lorauth`. 

Si: router_id=0x1122334455667788, seqno=0x1956 resulta en el
índice 11, se usará `c_A[11]`.

Para el caso de que el número de elementos es 100, si un nodo B recibe
un `TLV lorauth` de un nodo A seguirá los siguientes pasos:

1. Se trata de descifrar `Cipher` usando `CP` (clave pública de `C`).
2. Comprobar que en el mensaje descifrado esté incluído `prefix_A`
   que se anuncia en el *Update*.
3. Comprobrar que los dos útimos dígitos del mensaje descifrado
   sean `fd(fs(router_id, seqno), 2)`, donde `router_id` y `seqno`
   son los que se anuncian en el *Update*.

Si se cumplen estas tres condiciones la autenticación del *Update*
dado está completada, si no, se ignorará el *Update* correspondiente.

Con esta medida se dificulta el trabajo de obtener el orden correcto de
las cadenas cifradas `c_A` para un nodo A. Y dado que el método de
autenticación también comprueba el orden de la cadena descifrada se
hace más difícil el trabajo de suplantar completamente a un nodo A con
sólo capturar y reenviar los paquetes de autenticación.

#### Notas adicionales ####

Se puede agregar flexibilidad a la autenticación haciéndola no
obligatoria para todos los nodos, en ese caso los nodos que utilizan
la autenticación `babel-lorauth` incluirán en la tabla de fuentes
(*source table*) los registros `clen` y `cipher` sólo de los nodos
que los anuncien usando el `TLV lorauth`. Si se reciben *Updates* de
nodos que no usan el método de autenticación se crearán registros con
valores `null`en `clen` y `cipher` para estas actualizaciones.

Tambíen se puede hacer que los nodos que utilizan la autenticación
**prefieran** actualizaciones de rutas (*Updates*) de nodos que usen
el método de autenticación sobre nodos que no lo hacen.

De hecho se puede definir dos niveles de autenticación, el primer
nivel es **flexible** y como se menciona acepta actualizaciones de
rutas de nodos que no usan la autenticación, pero **prioriza** las
actualizaciones de nodos que sí las utilizan.

El segundo nivel es **rígido** y no acepta actualizacones de rutas de
nodos que no usan la autenticación (no usan el `TLV lorauth`).

#### Observaciones ####

* Cada nodo que participa en la red esta obligado a autenticarse ya que
  para que otros nodos tomen en cuenta el Update (actualizaciones de
  rutas) debe emitir cadenas `Cipher` válidas y los nodos que anuncian
  rutas de terceros **necesitan** reenviar las cadenas `Cipher` que ha
  confirmado como válidas.
* Cada nodo debería guardar la última cadena `Cipher` de cada nodo que
  autentica.
* Se requiere procesamiento extra para descifrar las cadenas `Cipher`
  con el algoritmo RSA.

